/**
 * <one line to give the program's name and a brief idea of what it does.>
 * Copyright (C) Aug 3, 2011  Isaias
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package redclient;

import java.awt.Image;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import redclient.Items.Issue;
import redclient.Items.Project;
import redclient.client.RedManager;
import redclient.ui.SettingsForm;
import redclient.ui.TimeEntriesForm;
import redclient.webclient.WebClientException;


/**
 *
 * @author Isaias
 * @file RedClient.java
 */
public class RedClient {

    private static File f;
    private static FileChannel channel;
    private static FileLock lock;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
/*
        try {
            f = new File("RingOnRequest.lock");
            // Check if the lock exist
            if (f.exists()) {
                // if exist try to delete it
                f.delete();
            }
            // Try to get the lock
            channel = new RandomAccessFile(f, "rw").getChannel();
            lock = channel.tryLock();
            if (lock == null) {
                // File is lock by other application
                channel.close();
                throw new RuntimeException("Only 1 instance of MyApp can run.");
            }
            // Add shutdown hook to release lock when application shutdown
            ShutdownHook shutdownHook = new ShutdownHook();
            Runtime.getRuntime().addShutdownHook(shutdownHook);

            //Your application tasks here..
            System.out.println("Running");
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        } catch (IOException e) {
            throw new RuntimeException("Could not start process.", e);
        }
*/


        try {
            // Set cross-platform Java L&F (also called "Metal")
            UIManager.setLookAndFeel(
                UIManager.getSystemLookAndFeelClassName());
        } 
        catch (UnsupportedLookAndFeelException e) {
           // handle exception
        }
        catch (ClassNotFoundException e) {
           // handle exception
        }
        catch (InstantiationException e) {
           // handle exception
        }
        catch (IllegalAccessException e) {
           // handle exception
        }

        if( ! SystemTray.isSupported() )
        {
            System.out.println("Your operating system does not support System Try icons. The application will not continue loading");
            JOptionPane.showMessageDialog(null, "Your operating system does not support System Try icons. The application will not continue loading", "Error", JOptionPane.ERROR_MESSAGE);
            return;
        }
        final SystemTray tray = SystemTray.getSystemTray();
        
        Image tryIconImage =  Toolkit.getDefaultToolkit().getImage(
                                        Toolkit.getDefaultToolkit()
                                               .getClass()
                                               .getResource("/redclient/ui/img/sandclock.png")
                              );

        final TrayIcon trayIcon = new TrayIcon(tryIconImage, "RedClient", null);
        trayIcon.setImageAutoSize(true);
        
        final JPopupMenu popupMenu = new JPopupMenu();
        
        popupMenu.addMouseListener(new java.awt.event.MouseAdapter() {
            @Override
            public void mouseExited(MouseEvent e) {
                super.mouseExited(e);
                if( e.getX() < 0 || e.getX() > popupMenu.getWidth() 
                    || e.getY() < 0 || e.getY() > popupMenu.getHeight())
                {
                    popupMenu.setVisible(false);
                }
            }
        });
        
        trayIcon.addMouseListener(new MouseAdapter(){
            public void mouseReleased(MouseEvent e) {
                if (!e.isPopupTrigger()) {
                    popupMenu.setLocation(e.getX()-5, e.getY());
                    popupMenu.setInvoker(popupMenu);
                    popupMenu.setVisible(true);
                }
            }
        });
        
        try{
            ImageIcon imageIcon = null;
            
            imageIcon = new ImageIcon(RedManager.class.getResource("/redclient/ui/img/refresh_icon.png"));
            JMenuItem refreshMenuItem = new JMenuItem("Refresh", imageIcon);
            
            imageIcon = new ImageIcon(RedManager.class.getResource("/redclient/ui/img/save_icon.png"));
            JMenuItem saveTimesItem = new JMenuItem("Time entries", imageIcon);
            
            imageIcon = new ImageIcon(RedManager.class.getResource("/redclient/ui/img/settings_icon.png"));
            JMenuItem settingsMenuItem = new JMenuItem("Settings", imageIcon);
            
            imageIcon = new ImageIcon(RedManager.class.getResource("/redclient/ui/img/redmine_icon.png"));
            JMenuItem myInstances = new JMenuItem("Remine instances", imageIcon);
            
            imageIcon = new ImageIcon(RedManager.class.getResource("/redclient/ui/img/abaut_icon.png"));
            JMenuItem aboutMenuItem = new JMenuItem("About", imageIcon);
            
            imageIcon = new ImageIcon(RedManager.class.getResource("/redclient/ui/img/application_exit_icon.png"));
            JMenuItem exitMenuItem = new JMenuItem("Exit", imageIcon);
            
            popupMenu.addSeparator();
            popupMenu.add(saveTimesItem);
            popupMenu.add(refreshMenuItem);
            popupMenu.addSeparator();
            popupMenu.add(settingsMenuItem);
            popupMenu.add(myInstances);
            popupMenu.addSeparator();
            popupMenu.add(aboutMenuItem);
            popupMenu.addSeparator();
            popupMenu.add(exitMenuItem);
            
            saveTimesItem.addActionListener(new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent e)
                {
                    //new TimeEntriesForm().setVisible(true);
                    //new NewJFrame().setVisible(true);
                    java.awt.EventQueue.invokeLater(new Runnable() {
                        public void run() {
                            //new TimeEntries().setVisible(true);
                            new TimeEntriesForm().setVisible(true);
                        }
                    });
                }
            });
            
            exitMenuItem.addActionListener(new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent e) {
                    int answer = JOptionPane.showConfirmDialog(null, "Do you want to close RedClient",
                                                "Closing RedClient", JOptionPane.OK_CANCEL_OPTION,
                                                JOptionPane.QUESTION_MESSAGE);
                    
                    if( answer == JOptionPane.OK_OPTION )
                    {
                        System.out.println("Exiting...");
                        System.exit(0);
                    }
                }
            });
            
            myInstances.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    SettingsForm sf = SettingsForm.getInstance();
                    sf.setVisible(true);
                }
            });
            
            ImageIcon clockIcon = new ImageIcon(RedManager.class.getResource("/redclient/ui/img/clock_icon.png"));
            ImageIcon newIssueIcon = new ImageIcon(RedManager.class.getResource("/redclient/ui/img/issue_add.png"));
            ImageIcon editIssueIcon = new ImageIcon(RedManager.class.getResource("/redclient/ui/img/issue_edit.png"));
            List<RedmineCredentials> credentials = RedmineCredentials.getCredentials();
            for(RedmineCredentials rc : credentials)
            {
                if ( rc.isActive() )
                {
                    try
                    {
                        JMenu rmMenuItem = new JMenu(rc.toString());
                        popupMenu.insert(rmMenuItem, 0);
                        RedManager manager = RedManager.Connect(rc);
                        List<Project> projects = manager.getProjects();
                        for(Project project : projects)
                        {
                            JMenu miProject = new JMenu(project.getName());

                            //JMenuItem logTimeMenuItem = new JMenuItem("Log time", clockIcon);
                            //logTimeMenuItem.addActionListener(new LogProjectTimeActionListener(project));

                            JMenuItem addNewIssueMenuItem = new JMenuItem("New issue", newIssueIcon);
                            addNewIssueMenuItem.addActionListener(new NewIssueActionListener(project));
                            miProject.addSeparator();
                            //miProject.add(logTimeMenuItem);
                            miProject.add(addNewIssueMenuItem);
                            rmMenuItem.insert(miProject, 0);

                            List<Issue> issues = project.getIssues();
                            for(Issue issue : issues)
                            {
                                JMenu issueMenu = new JMenu(issue.getSubject());

                                JMenuItem logIssueTimeMenuItem = new JMenuItem("Log time", clockIcon);
                                logIssueTimeMenuItem.addActionListener(new LogIssueTimeActionListener(issue));

                                imageIcon = new ImageIcon();
                                JMenuItem updateIssueMenuItem = new JMenuItem("Update issue", editIssueIcon);
                                updateIssueMenuItem.addActionListener(new UpdateIssueActionListener(issue));
                                issueMenu.add(logIssueTimeMenuItem);
                                issueMenu.add(updateIssueMenuItem);
                                miProject.insert(issueMenu, 0);
                            }
                        }
                    }
                    catch(WebClientException wce)
                    {
                        JOptionPane.showMessageDialog(null, wce.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                    }
                }
            }

            Runtime runtime = Runtime.getRuntime();
            System.out.printf("Free memory: %d, Total memory: %d, Max memory: %d\n", runtime.freeMemory(), runtime.totalMemory(), runtime.maxMemory());
           
            tray.add(trayIcon);

            JOptionPane.showMessageDialog(null, "RedClient is running, you can access it from your system tray", "RedClient started", JOptionPane.INFORMATION_MESSAGE);
        }
        /*
        */
        catch(Exception e)
        {
            JOptionPane.showMessageDialog(null, "Unexpected error, please contact your administrator", "Error", JOptionPane.ERROR_MESSAGE);
        }
    }

    static int secondaryMain( String args[] )
    {
        System.out.println("Already running");
        return 0;
    }

    public static void unlockFile() {
        // release and delete file lock
        try {
            if (lock != null) {
                lock.release();
                channel.close();
                f.delete();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    static class ShutdownHook extends Thread {

        public void run() {
            unlockFile();
        }
    }
}
